package org.mmtk.plan.scale;

import org.mmtk.plan.Trace;
import org.mmtk.policy.RawPageSpace;
import org.mmtk.utility.Constants;
import org.mmtk.utility.deque.SharedDeque;
import org.vmmagic.pragma.Uninterruptible;

/**
 * This abstract class implements the core functionality for a transitive
 * closure over the heap. This class holds the global state, TraceLocal and its
 * super-classes handle per-thread state.
 */
@Uninterruptible
public class ScaleTrace extends Trace implements Constants {
	private SharedDeque savedValuePool;
	private SharedDeque toEmptyValuePool;
	private SharedDeque savedRootLocationPool;

	public SharedDeque getToEmptyValuePool() {
		return this.toEmptyValuePool;
	}
	
	public SharedDeque getSavedRootLocationPool() {
		return this.savedRootLocationPool;
	}
	
	public SharedDeque getSavedValuePool() {
		return this.savedValuePool;
	}
	
	/**
	 * Constructor
	 */
	public ScaleTrace(RawPageSpace metaDataSpace) {
		super(metaDataSpace);
		this.toEmptyValuePool = new SharedDeque("toEmptyValuePool",metaDataSpace, 1);
		this.savedValuePool = new SharedDeque("savedValuePool",metaDataSpace, 1);
		this.savedRootLocationPool = new SharedDeque("copiedRootLocations", metaDataSpace, 1);
	}

	/**
	 * Prepare for a new collection pass.
	 */
	public void prepareNonBlocking() {
		super.prepareNonBlocking();
		this.toEmptyValuePool.prepareNonBlocking();
		this.savedValuePool.prepareNonBlocking();
		this.savedRootLocationPool.prepareNonBlocking();
	}

	/**
	 * Prepare for a new collection pass. All active GC threads take part.
	 */
	public void prepare() {
		super.prepare();
		this.toEmptyValuePool.prepare();
		this.savedValuePool.prepare();
		this.savedRootLocationPool.prepare();
	}

	/**
	 * Release resources after completing a collection pass.
	 */
	public void release() {
		super.release();
		this.toEmptyValuePool.reset();
		this.savedValuePool.reset();
		this.savedRootLocationPool.reset();
	}
}
